import axios, { AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse } from 'axios';

interface IResponseData<T> {
    success: boolean;
    code: number;
    message: string;
    data: any;
    total: number;
}

const config = {
    // withCredentials: true,
    baseURL: '',
    timeout: 10000,
    params: {}
};

class Http {
    // service: AxiosInstance;
    service;
    constructor(config: AxiosRequestConfig) {
        this.service = axios.create(config);

        /* 请求拦截  this.service.interceptors.request.use(config => config, error => Promise.reject(error))*/
        this.service.interceptors.request.use((config: AxiosRequestConfig) => {
            /* 业务逻辑
            1. 数据加密config.data
            2. 请求头加上token，结合vuex或localstorage：
                if(store.getters.token) config.headers['x-token'] = store.getters.token
                else 重定向
            3. ……
            */
            // 添加请求头示例代码
            if (sessionStorage.getItem('token')) {
                (config.headers as AxiosRequestHeaders).Authorization = sessionStorage.getItem('token') as string
                config.params['token'] = sessionStorage.getItem('token') as string;
            }
            return config
        }, (err: any) => {
            return Promise.reject(err) // 为了可以在代码中catch到错误信息
        })

        /* 响应拦截   this.service.interceptors.response.use(response => response.data, error => Promise.reject(error))*/
        this.service.interceptors.response.use((response: AxiosResponse<any>) => {
            /*
            1. 数据解密
            2. 根据 response.data.code 做不同的错误处理
            3. ……
            */
            return response
        }, (err: any) => {
            return Promise.reject(err)
        })
    }
    get<T>(url: string, params?: object, _object = {}): Promise<IResponseData<T>> {
        return this.service.get(url, { params, ..._object })
    }
    post<T>(url: string, data?: object, _object = {}): Promise<IResponseData<T>> {
        return this.service.post(url, data, _object)
    }
    put<T>(url: string, data?: object, _object = {}): Promise<IResponseData<T>> {
        return this.service.put(url, data, _object)
    }
    delete<T>(url: string, params?: any, _object = {}): Promise<IResponseData<T>> {
        return this.service.delete(url, { params, ..._object })
    }
}

export default new Http(config);